﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NewCenturyWubiQuery
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            LoadDecompositionDictionary();
            LoadRadicalFontFamily();
            radicalFont = new Font(radicalFontFamily, 72);
            QueryTextCodes(textBox.Text.Trim());
        }

        private Dictionary<string, string> decompositionDictionary;
        private FontFamily radicalFontFamily;
        private Font radicalFont;

        private void LoadDecompositionDictionary()
        {
            decompositionDictionary = new Dictionary<string, string>();
            Assembly assembly = Assembly.GetExecutingAssembly();
            using (Stream stream = assembly.GetManifestResourceStream("NewCenturyWubiQuery.wmwb06dec.txt"))
            using (TextReader reader = new StreamReader(stream))
            {
                while (true)
                {
                    string line = reader.ReadLine();
                    if (line == null)
                        break;
                    string[] items = line.Split(',');
                    string ch = items[0];
                    string dec = items[1];
                    decompositionDictionary.Add(ch, dec);
                }
            }
        }

        private void LoadRadicalFontFamily()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            using (Stream stream = assembly.GetManifestResourceStream("NewCenturyWubiQuery.wmwb06.ttf"))
            using (PrivateFontCollection fontColl = new PrivateFontCollection())
            {
                long length = stream.Length;
                byte[] bytes = new byte[length];
                stream.Read(bytes, 0, bytes.Length);
                unsafe
                {
                    fixed (byte* pbytes = bytes)
                    {
                        IntPtr pmemory = new IntPtr(pbytes);
                        fontColl.AddMemoryFont(pmemory, bytes.Length);
                        radicalFontFamily = fontColl.Families[0];
                    }
                }
            }
        }

        private void textBox_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox_KeyDown(object sender, KeyEventArgs e)
        {
        }

        private void clearQueryButton_Click(object sender, EventArgs e)
        {
            listView.Items.Clear();
        }

        private void doQueryButton_Click(object sender, EventArgs e)
        {
            QueryTextCodes(textBox.Text.Trim());
        }

        private void QueryTextCodes(string text)
        {
            listView.Items.Clear();
            foreach (int c in EnumUtf32(text))
            {
                string ch = char.ConvertFromUtf32(c);
                ListViewItem item = new ListViewItem();
                item.Text = ch;
                string dec;
                if (decompositionDictionary.TryGetValue(ch, out dec))
                {
                    string[] parts = dec.Split();
                    StringBuilder codeBuilder = new StringBuilder();
                    StringBuilder decompositionBuilder = new StringBuilder();
                    foreach (string part in parts)
                    {
                        string[] t = part.Split('+');
                        string a = t[0];
                        string i = t[1];
                        codeBuilder.Append(a);
                        decompositionBuilder.Append((char)(a[0] << 8 | int.Parse(i)));
                    }
                    item.SubItems.Add(codeBuilder.ToString());
                    ListViewItem.ListViewSubItem decSubItem = new ListViewItem.ListViewSubItem();
                    decSubItem.Text = decompositionBuilder.ToString();
                    decSubItem.Font = radicalFont;
                    item.SubItems.Add(decSubItem);
                }
                else
                {
                    item.SubItems.Add("?");
                }
                listView.Items.Add(item);
            }
        }

        private static IEnumerable<int> EnumUtf32(string value)
        {
            for (int i = 0; i < value.Length; i++)
                if (char.IsSurrogatePair(value, i))
                    yield return char.ConvertToUtf32(value, i++);
                else
                    yield return value[i];
        }
    }
}
